home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / sos3-2.lha / src / trc / trc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-24  |  29.7 KB  |  1,296 lines

  1. /* --------------------------------------------------------------------------
  2.  * Copyright 1992 by Forschungszentrum Informatik (FZI)
  3.  *
  4.  * You can use and distribute this software under the terms of the licence
  5.  * you should have received along with this program.
  6.  * If not or if you want additional information, write to
  7.  * Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
  8.  * D-7500 Karlsruhe 1, Germany.
  9.  * --------------------------------------------------------------------------
  10.  */
  11. /* This is a C-file (no C++); trc.h provides the appropriate C++     */
  12. /* interface.                                 */
  13.  
  14. /* ================================================================= */
  15. /* ===   MODULE - REALISATION                                    === */
  16. /* ================================================================= */
  17. /*                                                                   */
  18. /* MODULE-NAME: trc.c                    KEY : tt (short name)       */
  19. /*                                                                   */
  20. /* ORIGINAL                                                          */
  21. /* AUTHOR : name                         DATE: date                  */
  22. /*                                                                   */
  23. /* UPDATE HISTORY                                                    */
  24. /* AUTHOR : andreas geppert              DATE: 3-8-87                */
  25. /*          packed all tt - functions in one module, removed         */
  26. /*          superfluous adv-system-functions, introduced synonyms    */
  27. /*          defined in predef.h .                                    */
  28. /* AUTHOR : dietmar theobald (dt)        DATE: 3-9-91                */
  29. /*        removed most superfluous stuff, tried to turn this into  */
  30. /*        maintainable code                         */
  31. /* AUTHOR : walter zimmer (wz)           DATE: 19-11-91              */
  32. /*          inserted strdup-function (before only inserted  for      */
  33. /*          ultrix machines)                                         */ 
  34. /*                                                                   */
  35. /* ================================================================= */
  36. /*                                                                   */
  37. /* PURPOSE:                                                          */
  38. /*P         This module contains the functions of tt, making possible*/
  39. /*P         various kinds of test output.                            */
  40. /*                                                                   */
  41. /* SPECIALITIES:                                                     */
  42. /*S         ----                                                     */
  43. /*                                                                   */
  44. /* EXCEPTIONS, ERRORS:                                               */
  45. /*E         ----                                                     */
  46. /*                                                                   */
  47. /* ================================================================= */
  48.  
  49. /* ================================================================= */
  50. /* global declaration of system                                      */
  51. /* ================================================================= */
  52.  
  53. #include "sys.h"               /* programming guidelines          */
  54.  
  55. typedef int bool ;
  56. #ifndef TRUE
  57. #define TRUE 1
  58. #endif
  59. #ifndef FALSE
  60. #define FALSE 0
  61. #endif
  62.  
  63. typedef char *string ;
  64.  
  65. #include <errno.h>
  66.  
  67. /* ================================================================= */
  68. /* other C-libraries                                                 */
  69. /* ================================================================= */
  70.  
  71. #ifndef FILE
  72. #include <stdio.h>
  73.  
  74. #include <ctype.h>
  75. #include <fcntl.h>
  76. #include <sys/types.h>
  77. #include <sys/time.h>
  78. #include <stdlib.h>
  79. #endif
  80.  
  81. #include <malloc.h>
  82.  
  83. LOCAL char *strdup(src)              /* changed by wz 19/11/91  */
  84. char *src;
  85. {  return strcpy (malloc(strlen(src) + 1), src);
  86. }
  87.  
  88. #include <string.h>
  89.  
  90. extern   string        ttyname();
  91. extern     string     PTR environ;
  92.  
  93. extern   int        sys_nerr;
  94. extern   string            sys_errlist [];
  95.  
  96.  
  97. /* ================================================================= */
  98. /* EXPORT:                                                           */
  99. /* ================================================================= */
  100.  
  101. #ifdef NO_TT
  102. #undef NO_TT    // Assert that this module is part of the SOS library,
  103. #endif        // even if SOS is generated without trace code.
  104.  
  105. #include "trc.h"
  106.  
  107.  
  108. /* ================================================================= */
  109. /*                                                                   */
  110. /* REALISATION:                                                      */
  111. /*                                                                   */
  112. /* ================================================================= */
  113.  
  114. /* ================================================================= */
  115. /*    MODULE - CONSTANTS / MACROS:                                   */
  116. /* ================================================================= */
  117.  
  118. #define tt_MAXLEVEL  499
  119. #define tt_STDOUT    1
  120. #define tt_STDERR    2
  121. #define tt_DEL         0177
  122. #define tt_MAXCOLS   132
  123. #define tt_STDINDENT 2
  124. #define tt_MAXINDENT 60
  125.  
  126. #define tt_TRACE_COND(level) (level % 10 == 0)
  127.  
  128. #define T_ALLOC(v,t,l)    (v = (t *) tt_alloc ( "v", (l) * sizeof (t) ))
  129. #define T_CALLOC(v,t,l)    (v = (t *) tt_calloc ( "v", (l) * sizeof (t) ))
  130. #define T_FREE(v)    (tt_free ( "v", v ), v = NULL )
  131.  
  132.  
  133. /* ================================================================= */
  134. /*    MODULE - TYPES:                                                */
  135. /* ================================================================= */
  136.  
  137. /* ================================================================= */
  138. /*    MODULE - VARIABLES:                                            */
  139. /* ================================================================= */
  140.  
  141.  
  142. LOCAL    string            tt_command;
  143.      string            tt_faddr;
  144.      string            tt_laddr;
  145. LOCAL     string           tt_env_var = "SOSTRCLEVEL";
  146. LOCAL     string           tt_default_file = "tt.out";
  147. LOCAL     string           tt_filename;
  148.      char              tt_digits [] = "0123456789abcdef";
  149. LOCAL    char               tt_buf [512];
  150. LOCAL    char               tt_what [] = "@[$] TT 1.4 06/03/86 \
  151. 09:55:18 ADV/ORGA F. A. Meyer AG";
  152. LOCAL     int               tt_file = -1,
  153.                tt_tmp_file,
  154.                        tt_col  = 0,
  155.                        tt_indent = 0,
  156.                            tt_cmd_indx;
  157.      int               tt_do_indent = FALSE,
  158.                        tt_afdebug = FALSE,
  159.                        tt_screen = FALSE;
  160. LOCAL    time_t               tt_start;
  161. LOCAL    T_addrformat       tt_addrformat = T_HEX;
  162.  
  163. /* Erweiterung: */
  164.  
  165. EXPORT unsigned char tt_active [tt_MAXLEVEL + 1];
  166. /* Boole'sches Array; NEQ 0 fuer einen aktiven Level */
  167.  
  168. /* Ende der Erweiterung. Rainer Holzapfel, 26-Nov-1986 */
  169.  
  170.  
  171. /* ================================================================= */
  172. /*    MODULE - OPERATIONS:                                           */
  173. /* ================================================================= */
  174.  
  175. LOCAL    char    *appint (), *applong (), *appstr (),
  176.         *tt_app (), *tt_enc (), *tt_ecc (), *tt_enp ();
  177. LOCAL   void    tt_writefile ();
  178.  
  179.  
  180. /* ***************************************************************** */
  181. LOCAL int getchr ()
  182. /* ***************************************************************** */
  183. {  while (TRUE)
  184.    {  int c = tt_command[tt_cmd_indx++];
  185.       switch (c)
  186.       {  case 'T' : return ('t');
  187.      case '#' :
  188.      case 't' :
  189.      case '-' :
  190.      case ',' :
  191.      case '0' :
  192.      case '1' :
  193.      case '2' :
  194.      case '3' :
  195.      case '4' :
  196.      case '5' :
  197.      case '6' :
  198.      case '7' :
  199.      case '8' :
  200.      case '9' :
  201.      case EOS : return (c);
  202.       }
  203.    }
  204. } /* getchr */
  205.  
  206.  
  207. /* ***************************************************************** */
  208. LOCAL void ungetchr ()
  209. /* ***************************************************************** */
  210. {
  211.    tt_cmd_indx--;
  212. }  /* ungetchr */
  213.  
  214.  
  215. /* ***************************************************************** */
  216. LOCAL int getnum ()
  217. /* ***************************************************************** */
  218. {
  219.    int result = 0;
  220.    char c;
  221.  
  222.    while ('0' <= (c = getchr())  AND  c <= '9')
  223.       result = (result * 10) + (c - '0');
  224.  
  225.    ungetchr ();
  226.    return (result > tt_MAXLEVEL) ? tt_MAXLEVEL
  227.                  : result;
  228. } /* getnum */
  229.  
  230.  
  231. /* ***************************************************************** */
  232. LOCAL void interval (int_lo, int_hi)
  233. /* ***************************************************************** */
  234.  
  235.     int PTR int_lo,  PTR int_hi;
  236.  
  237. {    int    c;
  238.  
  239.    if ('0' <= (c = getchr())  AND  c <= '9')
  240.    {  ungetchr ();
  241.       CONT( int_lo ) = getnum ();
  242.       CONT( int_hi ) = CONT( int_lo );
  243.       c = getchr ();
  244.    }
  245.    else
  246.    {  CONT( int_lo ) = 0;
  247.       CONT( int_hi ) = -1;
  248.    }
  249.    if (c NEQ '-')
  250.       ungetchr ();
  251.    else
  252.    {  c = getchr ();
  253.       ungetchr ();
  254.  
  255.       CONT( int_hi ) = ('0' <= c  AND  c <= '9') ? getnum ()
  256.                          : tt_MAXLEVEL;
  257.    }
  258. } /* interval */
  259.  
  260.  
  261. /* ***************************************************************** */
  262. LOCAL void interpret (cmd_str)
  263. /* ***************************************************************** */
  264.  
  265.     string    cmd_str;
  266.  
  267. {    int    c;
  268.     int    stdtrace;
  269.     int    level, int_lo, int_hi;
  270.  
  271.    tt_command  = cmd_str;
  272.    tt_cmd_indx = 0;
  273.  
  274.    while (TRUE)
  275.    {  while ((c = getchr()) NEQ EOS  AND  c NEQ '#')
  276.      ;
  277.       if (c EQ EOS)
  278.      break;
  279.  
  280.       if ((c = getchr()) EQ 't')
  281.      stdtrace = TRUE;
  282.       else
  283.       {  ungetchr ();
  284.      stdtrace = FALSE;
  285.       }
  286.       interval (REF( int_lo ), REF( int_hi ));
  287.       if (stdtrace)
  288.      for (level = int_lo; level <= int_hi; level++ )
  289.         tt_active[level] = tt_TRACE_COND(level);
  290.       else
  291.      for (level = int_lo; level <= int_hi; level++ )
  292.         tt_active[level] = TRUE;
  293.    }
  294. } /* interpret */
  295. /* Ende der Ergaenzung. Rainer Holzapfel, 26-Nov-1986 */
  296.  
  297.  
  298. /* ***************************************************************** */
  299. LOCAL  void    tt_writefile ( ptr_into_tt_buf )
  300. /* ***************************************************************** */
  301.  
  302.     string    ptr_into_tt_buf;
  303.  
  304. {  if (tt_file < 0)
  305.       tt_init ( NULL );
  306.  
  307.    write ( tt_screen ? tt_STDERR : tt_file,
  308.        tt_buf,
  309.        (unsigned) (ptr_into_tt_buf - tt_buf) );
  310. }
  311.  
  312.  
  313. /* ***************************************************************** */
  314. LOCAL  string    tt_app ( txt )
  315. /* ***************************************************************** */
  316.  
  317.     string    txt;
  318.  
  319. {
  320.        string    pt;
  321.        int    i, l;
  322.  
  323.   if ( txt )
  324.   {  if ( CONT( txt ) EQ ' ' )
  325.        txt ++;
  326.      else if ( CONT( txt ) EQ tt_DEL )
  327.        CONT( txt ) = ' ';    /* const strings must not start with tt_DEL! */
  328.  
  329.      l = strlen ( txt );
  330.      if ( l > tt_MAXCOLS )
  331.      {  l = tt_MAXCOLS;   /* const strings must not exceed tt_MAXCOLS chars! */
  332.         txt [tt_MAXCOLS] = EOS;
  333.      }
  334.   }
  335.   else
  336.      l = 0;
  337.  
  338.   pt = tt_buf;
  339.  
  340.   if ( tt_col + l + 2 > tt_MAXCOLS )  /* note: tt_MAXINDENT << tt_MAXCOLS */
  341.   {  CONT( pt ++ ) = EOL;
  342.      tt_col = 0;
  343.   }
  344.  
  345.   if ( tt_do_indent  AND  tt_col < tt_indent )
  346.      for ( tt_col = i = tt_indent; i > 0; i -- )
  347.        CONT( pt ++ ) = ' ';
  348.  
  349.   if ( tt_col > ( tt_do_indent ? tt_indent : 0 ) )
  350.   {  CONT( pt ++ ) = ',';
  351.      CONT( pt ++ ) = ' ';
  352.      tt_col += 2;
  353.   }
  354.   if ( txt )
  355.   {  pt = appstr ( pt, txt );
  356.      CONT( pt ++ ) = ' ';
  357.      tt_col += l + 1;
  358.   }
  359.  
  360.   return ( pt );
  361. } /* tt_app */
  362.  
  363.  
  364. /* ***************************************************************** */
  365. LOCAL  string    appint ( s, i, l )
  366. /* ***************************************************************** */
  367.  
  368.        string    s;
  369.        int    i, l;
  370.  
  371. {
  372.  
  373.        int    flag = FALSE, zerofill = TRUE, k;
  374.  
  375.   if ( i < 0 )
  376.   {
  377.     CONT( s ++ ) = '-';
  378.     i = -i;
  379.   }
  380.  
  381.   if ( l < 0 )
  382.   {
  383.     zerofill = FALSE;
  384.     l = -l;
  385.   }
  386.  
  387.   while ( l > 5 )
  388.   {
  389.     CONT( s ++ ) = zerofill ? '0' : ' ';
  390.     l --;
  391.   }
  392.  
  393.   if ( l EQ 5 )
  394.     flag = TRUE;
  395.  
  396.   k = i / 10000;
  397.   i %= 10000;
  398.  
  399.   if ( flag OR k )
  400.   {
  401.     if ( k OR zerofill )
  402.       CONT( s ++ ) = k + '0';
  403.     else
  404.       CONT( s ++ ) = ' ';
  405.  
  406.     flag = TRUE;
  407.   }
  408.   else if ( l >= 4 )
  409.     flag = TRUE;
  410.  
  411.   k = i / 1000;
  412.   i %= 1000;
  413.  
  414.   if ( flag OR k )
  415.   {
  416.     if ( k OR zerofill )
  417.       CONT( s ++ ) = k + '0';
  418.     else
  419.       CONT( s ++ ) = ' ';
  420.  
  421.     flag = TRUE;
  422.   }
  423.   else if ( l >= 3 )
  424.     flag = TRUE;
  425.  
  426.   k = i / 100;
  427.   i %= 100;
  428.  
  429.   if ( flag OR k )
  430.   {
  431.     if ( k OR zerofill )
  432.       CONT( s ++ ) = k + '0';
  433.     else
  434.       CONT( s ++ ) = ' ';
  435.  
  436.     flag = TRUE;
  437.   }
  438.   else if ( l >= 2 )
  439.     flag = TRUE;
  440.  
  441.   k = i / 10;
  442.   i %= 10;
  443.  
  444.   if ( flag OR k )
  445.   {
  446.     if ( k OR zerofill )
  447.       CONT( s ++ ) = k + '0';
  448.     else
  449.       CONT( s ++ ) = ' ';
  450.   }
  451.  
  452.   CONT( s ++ ) = i + '0';
  453.   CONT( s ) = EOS;
  454.   return ( s );
  455. } /* appint */
  456.  
  457.  
  458. /* ***************************************************************** */
  459. LOCAL  string    applong ( s, l )
  460. /* ***************************************************************** */
  461.  
  462.        string    s;
  463.        long    l;
  464.  
  465. {
  466.  
  467.     char    buf [16];
  468.        string    pt;
  469.  
  470.   if ( l < 0 )
  471.   {
  472.     CONT( s ++ ) = '-';
  473.     l = -l;
  474.   }
  475.  
  476.   if ( NOT  ( l ) )
  477.   {
  478.     CONT( s ++ ) = '0';
  479.     CONT( s ) = EOS;
  480.     return ( s );
  481.   }
  482.  
  483.   for ( ( buf [15] = EOS, pt = buf + 14 ); l; pt -- )
  484.   {
  485.     CONT( pt ) = (char) ( l MOD 10 ) + '0';
  486.     l = l / 10;
  487.   }
  488.  
  489.   while ( CONT( s ++ ) = CONT(  ++ pt ) ) ;
  490.  
  491.   return ( s - 1 );
  492. } /* applong */
  493.  
  494.  
  495. /* ***************************************************************** */
  496. LOCAL  string    appstr ( s1, s2 )
  497. /* ***************************************************************** */
  498.  
  499.        string    s1;
  500.         string  s2;
  501.  
  502. {
  503.  
  504.   while ( CONT( s1 ++ ) = CONT( s2 ++ ) ) ;
  505.  
  506.   return ( s1 - 1 );
  507. } /* appstr */
  508.  
  509.  
  510. /* ***************************************************************** */
  511. LOCAL  string    tt_ecc ( pt, val )
  512. /* ***************************************************************** */
  513.  
  514.     string    pt;
  515.     int    val;
  516.  
  517. {static int     C_escapes [] = { '0', EOS, EOS, EOS, EOS, EOS, EOS, 'a',
  518.                   'b', 't', 'n', 'v', 'f', 'r' };
  519.     int     esc_char;
  520.  
  521.   if ( isascii ( val ) AND isprint ( val ) )
  522.   {  if ( val EQ ' ' )
  523.      {  CONT( pt ++ ) = val = '.';
  524.         tt_col ++;
  525.      }
  526.  
  527.      CONT( pt ++ ) = val;
  528.      tt_col ++;
  529.   }
  530.   else if ( val <= '\r' AND ( esc_char = C_escapes [val] ) )
  531.   {  CONT( pt ++ ) = '\\';
  532.      CONT( pt ++ ) = esc_char;
  533.      tt_col += 2;
  534.   }
  535.   else
  536.   {  CONT( pt ++ ) = '\\';
  537.      CONT( pt ++ ) = tt_digits [((unsigned)val >> 6) BITAND 0x3];
  538.      CONT( pt ++ ) = tt_digits [((unsigned)val >> 3) BITAND 0x7];
  539.      CONT( pt ++ ) = tt_digits [val BITAND 0x7];
  540.      tt_col += 3;
  541.   }
  542.   return ( pt );
  543.  
  544. } /* tt_ecc */
  545.  
  546.  
  547. /* ***************************************************************** */
  548. LOCAL    string    tt_eccs ( pt, c, count )
  549. /* ***************************************************************** */
  550.  
  551.        string    pt;
  552.         int     c;
  553.        int    count;
  554.  
  555. {    int    oldcol = tt_col;
  556.     char    buf[20];
  557.     string  buf_pt = buf;
  558.  
  559.   if ( count > 1 )
  560.   {  buf_pt = tt_enc ( buf_pt, (long) count, T_DEC );
  561.      CONT( buf_pt ++ ) = '*';
  562.      tt_col ++;
  563.   }
  564.   buf_pt = tt_ecc ( buf_pt, (unsigned)c );
  565.   CONT( buf_pt ++ ) = ' ';
  566.   CONT( buf_pt    ) = EOS;
  567.  
  568.   if ( tt_col < tt_MAXCOLS )
  569.      tt_col = oldcol;
  570.   else
  571.   {  CONT( pt ++ ) = EOL;
  572.      tt_writefile ( pt );
  573.  
  574.      pt = tt_buf;
  575.      CONT( pt ++ ) = ' ';
  576.      tt_col = 1;
  577.   }
  578.   pt = appstr ( pt, buf );
  579.   tt_col += buf_pt - buf;
  580.   
  581.   return ( pt );
  582. } /* tt_eccs */
  583.  
  584.  
  585. /* ***************************************************************** */
  586. LOCAL  string    tt_enc ( s, val, mode )
  587. /* ***************************************************************** */
  588.  
  589.     string    s;
  590.        long    val;
  591.        T_addrformat    mode;
  592.  
  593. {
  594.     char    hbuf [20];
  595.        string    pt = hbuf + 19;
  596.        bool    neg = FALSE;
  597.     long    help;
  598.     int    shft;  /* = 4 */
  599.  
  600.   CONT( pt -- ) = EOS;
  601.  
  602.   if ( val EQ 0 )
  603.     CONT( pt -- ) = '0';
  604.  
  605.   else if ( mode EQ T_UNS OR mode EQ T_DEC )
  606.   {
  607.     if ( mode EQ T_DEC AND val < 0 )
  608.     {
  609.       neg = TRUE;
  610.       val = -val;
  611.     }
  612.  
  613.     for ( ; val; val /= 10 )
  614.       CONT( pt -- ) = tt_digits [val MOD 10];
  615.  
  616.     if ( neg )
  617.       CONT( pt -- ) = '-';
  618.   }
  619.   else
  620.   {
  621.     if ( mode EQ T_HEX )
  622.     {
  623.       CONT( s ++ ) = 'X';
  624.       help = 0xfL;
  625.       shft = 4;
  626.     }
  627.     else
  628.     {
  629.       CONT( s ++ ) = '0';
  630.       help = 07L;
  631.       shft = 3;
  632.     }
  633.  
  634.     CONT( pt -- ) = tt_digits [val BITAND help];
  635.     val = ( val >> shft ) BITAND
  636.         BITCPL( ( help << ( sizeof (long) * 8 - shft ) ) );
  637.  
  638.     while ( val )
  639.     {
  640.       CONT( pt -- ) = tt_digits [val BITAND help];
  641.       val >>= shft;
  642.     }
  643.   }
  644.  
  645.   tt_col += strlen ( ++ pt );
  646.   return ( appstr ( s, pt ) );
  647. } /* tt_enc */
  648.  
  649.  
  650. /* ***************************************************************** */
  651. LOCAL  string tt_enp ( pt, val )
  652. /* ***************************************************************** */
  653.  
  654.        string    pt;
  655.     string    val;
  656.  
  657. {
  658.        long    hval = (long) val;
  659.  
  660.   if ( NOT val )
  661.     return ( appstr ( pt, "NULL" ) );
  662.  
  663.   pt = tt_enc ( pt, hval BITAND 0xffffL, tt_addrformat );
  664.  
  665.   return ( pt );
  666. } /* tt_enp */
  667.  
  668.  
  669. /* ***************************************************************** */
  670. LOCAL void tt_err ( action, file )
  671. /* ***************************************************************** */
  672.  
  673.        string    action;
  674.         string  file;
  675.  
  676. {
  677.  
  678.        string    pt;
  679.  
  680.   tt_nl ();
  681.  
  682.   pt = tt_app ( "Cannot" );
  683.   pt = appstr ( pt, action );
  684.  
  685.   if ( file AND CONT( file ) )
  686.   {
  687.     CONT( pt ++ ) = ' ';
  688.     CONT( pt ++ ) = '\'';
  689.     pt = appstr ( pt, file );
  690.     CONT( pt ++ ) = '\'';
  691.   }
  692.  
  693.   if ( errno )
  694.   {
  695.     CONT( pt ++ ) = ':';
  696.     CONT( pt ++ ) = ' ';
  697.  
  698.     if ( errno < sys_nerr )
  699.       pt = appstr ( pt, sys_errlist [errno] );
  700.     else
  701.     {
  702.       pt = appstr ( pt, "Unknown Error #" );
  703.       pt = appint ( pt, errno, 0 );
  704.     }
  705.   }
  706.  
  707.   CONT( pt ++ ) = EOL;
  708.   tt_col = 0;
  709.   tt_writefile ( pt );
  710. } /* tt_err */
  711.  
  712.  
  713. /* ***************************************************************** */
  714. EXPORT  string    tt_alloc ( s, n )
  715. /* ***************************************************************** */
  716.  
  717. string    s;
  718. int    n;
  719.  
  720. {
  721.        string    pt = malloc ( ( unsigned int ) n );
  722.  
  723.   T_PROC  ( "tt_alloc" );
  724.   if (tt_afdebug)
  725.   {
  726.      tt_s ( tt_proc, s ); TI (n); tt_p ( "=", pt );
  727.      tt_nl ();
  728.   }
  729.  
  730.   if ( NOT  pt )
  731.   {
  732.     perror ( tt_proc );
  733.     abort ();
  734.   }
  735.  
  736.   if ( NOT  tt_faddr )
  737.     tt_faddr =  pt;
  738.  
  739.   if ( pt > tt_laddr )
  740.     tt_laddr =  pt + n - 1 ;
  741.  
  742.   return ( pt );
  743. } /* tt_alloc */
  744.  
  745.  
  746. /* ***************************************************************** */
  747. EXPORT string    tt_calloc ( s, n )
  748. /* ***************************************************************** */
  749.  
  750. string    s;
  751. int    n;
  752.  
  753. {
  754.        string    cpt;
  755.     string  pt = malloc ( ( unsigned int ) n );
  756.  
  757.   T_PROC  ( "tt_calloc" );
  758.   if (tt_afdebug)
  759.   {
  760.      tt_s ( tt_proc, s ); TI (n); tt_p ( "=", pt );
  761.      tt_nl ();
  762.   }
  763.  
  764.   if ( NOT  pt )
  765.   {
  766.     perror ( tt_proc );
  767.     abort ();
  768.   }
  769.  
  770.   if ( NOT  tt_faddr )
  771.     tt_faddr =  pt;
  772.  
  773.   if ( pt > tt_laddr )
  774.     tt_laddr =  pt + n - 1;
  775.  
  776.   for ( cpt = pt; n > 0; n -- )
  777.     CONT( cpt ++ ) = EOS;
  778.  
  779.   return ( pt );
  780. } /* tt_calloc */
  781.  
  782.  
  783. /* ***************************************************************** */
  784. EXPORT  void  tt_free ( s, p )
  785. /* ***************************************************************** */
  786.  
  787. string    s;
  788. string  p;
  789.  
  790. {
  791.   if (tt_afdebug)
  792.   {
  793.      tt_s ( "tt_free", s ); tt_p ( "=", p );
  794.      tt_nl ();
  795.   }
  796.  
  797.   if ( p < tt_faddr OR p > tt_laddr )
  798.   {
  799.     tt_p ( "can't tt_free", p );
  800.     return;
  801.   }
  802.   free ( p );
  803. } /* tt_free */
  804.  
  805.  
  806. /* ***************************************************************** */
  807. EXPORT  void tt_redef ( str )
  808. /* ***************************************************************** */
  809.  
  810.        string    str;
  811.  
  812. {
  813.     int    i, j;
  814.  
  815.    for ( i = tt_MAXLEVEL; i > 0; --i ) tt_active [i] = FALSE;
  816.    tt_active[0] = TRUE;
  817.      /* Richard 25.1.88: set level 0 always! */
  818.  
  819.    while ( CONT( str ) )
  820.    {  if (CONT( str ) EQ '#')
  821.       {  interpret ( str );
  822.      break;
  823.       }
  824.       else if (isdigit ( CONT(str) ))
  825.       {
  826.      int level = atoi ( str ),
  827.          j     = (level > tt_MAXLEVEL) ? tt_MAXLEVEL
  828.                        : level;
  829.      while (j >= 0)
  830.         tt_active [j --] = TRUE;
  831.  
  832.      while (isdigit( CONT(++ str) ))
  833.         ;
  834.       }
  835.       else
  836.          switch ( CONT(str ++) )
  837.      {  case 'I': case 'i': tt_do_indent  = TRUE;  break;
  838.         case 'S': case 's': tt_screen     = TRUE;  break;
  839.               case 'a': tt_afdebug    = 1;     break;
  840.         case 'A':           tt_afdebug    = 2;     break;
  841.         case 'H': case 'h': tt_addrformat = T_HEX; break;
  842.         case 'D': case 'd': tt_addrformat = T_DEC; break;
  843.         case 'O': case 'o': tt_addrformat = T_OCT; break;
  844.         case 'U': case 'u': tt_addrformat = T_UNS; break;
  845.         case 'N': case 'n': tt_active[0]  = FALSE; break;
  846.            /* Richard 25.1.88: reset level 0 */
  847.      }
  848.    }
  849. } /* tt_redef */
  850.  
  851.  
  852. /* ***************************************************************** */
  853. EXPORT  void  tt_init ( pname )
  854. /* ***************************************************************** */
  855.  
  856.        string    pname;
  857.  
  858. {
  859.        struct    tm    PTR tm;
  860.     struct    tm    PTR localtime ();
  861.        string        PTR env;
  862.     string      pt = tt_what;
  863.     string      envstr;
  864.     int        i, j;
  865.  
  866.    if ( tt_file >= 0 )
  867.      return;
  868.  
  869.    if (envstr = getenv (tt_env_var))
  870.    {  tt_redef (envstr);
  871.       tt_tmp_file = FALSE;
  872.    }
  873.    else
  874.    {  for ( i = tt_MAXLEVEL; i > 0; --i ) tt_active [i] = FALSE;
  875.       tt_active[0] = TRUE;
  876.       tt_tmp_file  = TRUE;
  877.    }
  878.    time ( REF( tt_start ) );
  879.    tm = localtime ( REF( tt_start ) );
  880.  
  881.    if ( pname EQ NULL  OR  strlen ( pname ) EQ 0 )
  882.       pname = tt_default_file;
  883.  
  884.   if ( ( tt_file = creat ( pname, 0666 ) ) < 0 )
  885.   {
  886.     perror ( pname );
  887.     sleep ( 10 );
  888.     exit ( 99 );
  889.   }
  890.   tt_filename = strdup ( pname );
  891.  
  892.   fchmod ( tt_file, 0666 );
  893.   fcntl ( tt_file, F_SETFD, 1 );
  894.  
  895.   pt = tt_buf;
  896.   if (envstr)
  897.   {  pt = appstr ( pt, tt_env_var );
  898.      CONT( pt++ ) = '=';
  899.      pt = appstr ( pt, envstr );
  900.      CONT( pt++ ) = EOL;
  901.   }
  902.   pt = appstr ( pt, "pid " );
  903.   pt = appint ( pt, getpid (), 0 );
  904.  
  905.   pt = appstr ( pt, "; start " );
  906.   pt = appint ( pt, tm -> tm_hour, 0 );
  907.   CONT( pt ++ ) = ':';
  908.   pt = appint ( pt, tm -> tm_min, 2 );
  909.   CONT( pt ++ ) = ':';
  910.   pt = appint ( pt, tm -> tm_sec, 2 );
  911.   pt = appstr ( pt, "; tty " );
  912.   if (envstr = ttyname (tt_STDOUT))
  913.      pt = appstr ( pt, envstr );
  914.   else
  915.      CONT ( pt ++ ) = '?';
  916.   CONT( pt ++ ) = EOL;
  917.  
  918.   write ( tt_file, tt_buf, ( unsigned int ) ( pt - tt_buf ) );
  919.  
  920. } /* tt_init */
  921.  
  922.  
  923. /* ***************************************************************** */
  924. EXPORT  void  tt_exit ()
  925. /* ***************************************************************** */
  926.  
  927. {
  928.  
  929. struct    tbuffer {
  930.   long    p_user, p_sys,
  931.     c_user, c_sys; } buf;
  932.        long    alltime, cputime;
  933.        string    pt;
  934.     time_t    endtime;
  935.        struct    tm    PTR tm;
  936.     struct    tm    PTR localtime ();
  937.  
  938.   if ( tt_file < 0 )
  939.     return;
  940.  
  941.   if ( tt_tmp_file )
  942.      unlink ( tt_filename );
  943.   else
  944.   {  tt_nl ();
  945.  
  946.      times ( REF(  buf ) );
  947.      time    ( REF(  endtime ) );
  948.      tm = localtime ( REF( endtime ) );
  949.  
  950.      cputime = ( buf.p_user * 100 ) / 60;
  951.      pt = applong ( tt_buf, cputime / 100 );
  952.      CONT( pt ++  )= '.';
  953.      CONT( pt ++ ) = ( cputime MOD 100 ) / 10 + '0';
  954.      CONT( pt ++ ) = cputime MOD 10 + '0';
  955.      strcpy ( pt, " user, " );
  956.      cputime = ( buf.p_sys * 100 ) / 60;
  957.      pt = applong ( pt + 7, cputime / 100 );
  958.      CONT( pt ++ ) = '.';
  959.      CONT( pt ++ ) = ( cputime MOD 100 ) / 10 + '0';
  960.      CONT( pt ++ ) = cputime MOD 10 + '0';
  961.      strcpy ( pt, " sys, " );
  962.      alltime = endtime - tt_start;
  963.      pt = appint ( pt + 6, (int) (alltime / 3600), 0 );
  964.      alltime %= 3600;
  965.      CONT(  pt ++ ) = ':';
  966.      pt = appint ( pt, (int) (alltime / 60), 2 );
  967.      CONT(  pt ++ ) = ':';
  968.      pt = appint ( pt, (int) (alltime MOD 60), 2 );
  969.      strcpy ( pt, " real, end at " );
  970.      pt = appint ( pt + 14, tm -> tm_hour, 0 );
  971.      CONT( pt ++ ) = ':';
  972.      pt = appint ( pt, tm -> tm_min, 2 );
  973.      CONT( pt ++ ) = ':';
  974.      pt = appint ( pt, tm -> tm_sec, 2 );
  975.      CONT( pt ++ ) = EOL;
  976.      CONT( pt ) = EOS;
  977.  
  978.      write ( tt_file, tt_buf, ( unsigned int ) ( pt - tt_buf ) );
  979.   }
  980.   close ( tt_file );
  981.   free ( tt_filename );
  982.  
  983.   tt_file = -1;
  984. } /* tt_exit */
  985.  
  986.  
  987. /* ***************************************************************** */
  988. EXPORT  void  tt_enter ( proc )
  989. /* ***************************************************************** */
  990.  
  991.        string    proc;
  992.  
  993. {
  994.        string    pt;
  995.  
  996.   tt_nl ();
  997.  
  998.   pt = appstr ( tt_app ( "Enter {" ), proc );
  999.   tt_col += strlen ( proc );
  1000.   tt_writefile ( pt );
  1001.  
  1002.   tt_indent = ( tt_indent + tt_STDINDENT ) MOD tt_MAXINDENT;
  1003. } /* tt_enter */
  1004.  
  1005.  
  1006. /* ***************************************************************** */
  1007. EXPORT  void  tt_leave ( proc )
  1008. /* ***************************************************************** */
  1009.  
  1010.        string    proc;
  1011.  
  1012. {
  1013.        string    pt;
  1014.  
  1015.   tt_indent = ( tt_indent + tt_MAXINDENT-tt_STDINDENT ) MOD tt_MAXINDENT;
  1016.   tt_nl ();
  1017.  
  1018.   pt = appstr ( tt_app ( "Leave }" ), proc );
  1019.   tt_col += strlen ( proc );
  1020.   tt_writefile ( pt );
  1021.  
  1022. } /* tt_leave */
  1023.  
  1024.  
  1025. /* ***************************************************************** */
  1026. EXPORT  void  tt_nl ()
  1027. /* ***************************************************************** */
  1028.  
  1029. {
  1030.   if ( tt_col )
  1031.   {  tt_writefile ( appstr ( tt_buf, "\n" ) );
  1032.      tt_col = 0;
  1033.   }
  1034. }
  1035.  
  1036.  
  1037. /* ***************************************************************** */
  1038. EXPORT  void tt_txt ( txt )
  1039. /* ***************************************************************** */
  1040.  
  1041.     string    txt;
  1042.  
  1043. {  tt_writefile ( tt_app ( txt ) - 1 );
  1044.    tt_col -= 1;
  1045. }
  1046.  
  1047.  
  1048. /* ***************************************************************** */
  1049. EXPORT  void  tt_i ( txt, val )
  1050. /* ***************************************************************** */
  1051.  
  1052.     string    txt;
  1053.        int    val;
  1054.  
  1055. {  tt_writefile ( tt_enc ( tt_app(txt), (long) val, T_DEC ) );
  1056. }
  1057.  
  1058.  
  1059. /* ***************************************************************** */
  1060. EXPORT  void  tt_u ( txt, val )
  1061. /* ***************************************************************** */
  1062.  
  1063.     string     txt;
  1064.        unsigned val;
  1065.  
  1066. {  tt_writefile ( tt_enc ( tt_app(txt), (long) val, T_UNS ) );
  1067. }
  1068.  
  1069.  
  1070. /* ***************************************************************** */
  1071. EXPORT void tt_o ( txt, val )
  1072. /* ***************************************************************** */
  1073.  
  1074.     string     txt;
  1075.        unsigned val;
  1076.  
  1077. {  tt_writefile ( tt_enc ( tt_app(txt), (long) val, T_OCT ) );
  1078. }
  1079.  
  1080.  
  1081. /* ***************************************************************** */
  1082. EXPORT  void  tt_x ( txt, val )
  1083. /* ***************************************************************** */
  1084.  
  1085.     string     txt;
  1086.        unsigned val;
  1087.  
  1088. {  tt_writefile ( tt_enc ( tt_app(txt), (long) val, T_HEX ) );
  1089. }
  1090.  
  1091.  
  1092. /* ***************************************************************** */
  1093. EXPORT  void  tt_li ( txt, val )
  1094. /* ***************************************************************** */
  1095.  
  1096.     string    txt;
  1097.        long    val;
  1098.  
  1099. {  tt_writefile ( tt_enc ( tt_app(txt), val, T_DEC ) );
  1100. }
  1101.  
  1102.  
  1103. /* ***************************************************************** */
  1104. EXPORT  void  tt_lo ( txt, val )
  1105. /* ***************************************************************** */
  1106.  
  1107.     string    txt;
  1108.        long    val;
  1109.  
  1110. {  tt_writefile ( tt_enc ( tt_app(txt), val, T_OCT ) );
  1111. }
  1112.  
  1113.  
  1114. /* ***************************************************************** */
  1115. EXPORT  void  tt_lx ( txt, val )
  1116. /* ***************************************************************** */
  1117.  
  1118.     string    txt;
  1119.        long    val;
  1120.  
  1121. {  tt_writefile ( tt_enc ( tt_app(txt), val, T_HEX ) );
  1122. }
  1123.  
  1124.  
  1125. /* ***************************************************************** */
  1126. EXPORT  void  tt_c ( txt, val )
  1127. /* ***************************************************************** */
  1128.  
  1129.     string    txt;
  1130.        int    val;
  1131.  
  1132. {  tt_writefile ( tt_ecc ( tt_app(txt), val ) );
  1133. }
  1134.  
  1135.  
  1136. /* ***************************************************************** */
  1137. EXPORT  void  tt_s ( txt, val )
  1138. /* ***************************************************************** */
  1139.  
  1140.        string    txt;
  1141.         string  val;
  1142.  
  1143. {
  1144.        string    pt;
  1145.        int    l = val ? strlen ( val ) : 6;
  1146.  
  1147.   if ( tt_col + l + ( txt ? strlen ( txt ) : 0 ) > tt_MAXCOLS )
  1148.      tt_nl ();
  1149.  
  1150.   pt = tt_app ( txt );
  1151.  
  1152.   if ( NOT val )
  1153.   {  pt = appstr ( pt, "<NULL>" );
  1154.      tt_col += 6;
  1155.   }
  1156.   else
  1157.   {  CONT( pt ++ ) = '<';
  1158.      pt = tt_enp ( pt, val );
  1159.      CONT( pt ++ ) = '>';
  1160.      CONT( pt ++ ) = ' ';
  1161.      CONT( pt ++ ) = '\'';
  1162.      tt_col += 4;
  1163.  
  1164.      while ( TRUE )
  1165.      {  string end = val + (tt_MAXCOLS - tt_col) - 2;
  1166.  
  1167.     while ( val <= end  AND  CONT( val ) )
  1168.     {  CONT ( pt ++ ) = CONT ( val );
  1169.        if ( CONT( val ++ ) EQ EOL )
  1170.        {  -- pt;
  1171.           break;
  1172.        }
  1173.        ++ tt_col;
  1174.     }
  1175.     if ( CONT( val ) )
  1176.     {  CONT ( pt ++ ) = EOL;
  1177.        tt_writefile ( pt );
  1178.        pt     = tt_buf;
  1179.        tt_col = 0;
  1180.     }
  1181.     else
  1182.        break;
  1183.      }
  1184.      CONT ( pt ++ ) = '\'';
  1185.      ++ tt_col;
  1186.   }
  1187.   tt_writefile ( pt );
  1188.  
  1189. } /* tt_s */
  1190.  
  1191.  
  1192. /* ***************************************************************** */
  1193. EXPORT  void tt_a ( txt, val, nel )
  1194. /* ***************************************************************** */
  1195.  
  1196.     string    txt;
  1197.        string    val;
  1198.        int    nel;
  1199.  
  1200. {
  1201.        int    count;
  1202.     int    printable_max_seq;
  1203.        string    pt;
  1204.         int     lastc;
  1205.         string  tt_app();
  1206.     string  tt_enp();
  1207.  
  1208.   pt = tt_app ( txt );
  1209.   CONT( pt ++ ) = '<';
  1210.   pt = tt_enp ( pt, val );
  1211.   CONT( pt ++ ) = '>';
  1212.   CONT( pt ++ ) = ' ';
  1213.   tt_col += 3;
  1214.  
  1215.   tt_writefile ( pt );
  1216.  
  1217.   if ( NOT  val )
  1218.      return;
  1219.  
  1220.   pt = tt_buf;
  1221.  
  1222.   if ( nel <= 0 )
  1223.      nel = strlen ( val ) + 1;                /* note: nel >= 1! */
  1224.  
  1225.   printable_max_seq = ( nel > 50 ? 3 : 50 );
  1226.  
  1227.   lastc = CONT( val ++ );
  1228.   count = 1;
  1229.   while ( TRUE )
  1230.   {  if ( --nel > 0  AND  lastc EQ CONT( val ) )
  1231.         count ++;
  1232.      else
  1233.      {  if ( isprint ( lastc )  AND  count <= printable_max_seq )
  1234.        while ( --count >= 0 )
  1235.           pt = tt_eccs ( pt, lastc, 1 );
  1236.     else
  1237.        pt = tt_eccs ( pt, lastc, count );
  1238.  
  1239.     if ( nel EQ 0 )
  1240.        break;
  1241.  
  1242.         count = 1;
  1243.         lastc = CONT( val );
  1244.      }
  1245.      val ++;
  1246.   }
  1247.   CONT( pt ++ ) = EOL;
  1248.   tt_writefile ( pt );
  1249.   tt_col = 0;
  1250.  
  1251. } /* tt_a */
  1252.  
  1253.  
  1254. /* ***************************************************************** */
  1255. EXPORT  void  tt_sa ( txt, val, nel )
  1256. /* ***************************************************************** */
  1257.  
  1258.     string    txt;
  1259.        string    PTR val;
  1260.        int    nel;
  1261.  
  1262. {
  1263.        int    cnt;
  1264.        string    pt = tt_app ( txt );
  1265.     char    buf [10];
  1266.  
  1267.   CONT( pt ++ ) = EOL;
  1268.   tt_col = 0;
  1269.   tt_writefile ( pt );
  1270.  
  1271.   for ( cnt = 0; nel > 0; cnt ++, val ++, nel -- )
  1272.   {
  1273.     pt = buf;
  1274.     CONT( pt ++ ) = tt_DEL;
  1275.     CONT( pt ++ ) = '[';
  1276.     CONT( pt ++ ) = cnt / 10 + '0';
  1277.     CONT( pt ++ ) = cnt MOD 10 + '0';
  1278.     CONT( pt ++ ) = ']';
  1279.     CONT( pt    ) = EOS;
  1280.  
  1281.     tt_s ( buf, CONT( val ) );
  1282.     tt_nl ();
  1283.   }
  1284. } /* tt_sa */
  1285.  
  1286.  
  1287. /* ***************************************************************** */
  1288. EXPORT  void  tt_p ( txt, val )
  1289. /* ***************************************************************** */
  1290.  
  1291.     string    txt;
  1292.     string    val;
  1293.  
  1294. {  tt_writefile ( tt_enp ( tt_app(txt), val ) );
  1295. }
  1296.